//
//  UMLogFilesManager.m
//  PetGuGu
//
//  Created by _G.R.M. on 2023/8/16.
//

#import "UMLogFilesManager.h"
#import "ZipArchive+ZipDir.h"
#import "NSString+Extension.h"

#define LogFileNamePrefix @"Lefant"

@implementation UMGlobalLogFiles

+ (void)setupLogFiles {

    DDOSLogger *osLogger = [DDOSLogger sharedInstance];
    
    UMGlobalLogFileFormatter *formatter = [[UMGlobalLogFileFormatter alloc] init];
    formatter.osFormat = YES;
    [osLogger setLogFormatter:formatter];
    [DDLog addLogger:osLogger];
//    [DDLog addLogger:[DDTTYLogger sharedInstance]];
    
    UMGlobalLogFileDir *fileManager = [[UMGlobalLogFileDir alloc] initWithLogsDirectory:[[self class] logsDir]];
    fileManager.logFilesDiskQuota = 1024 * 1024 * 20; // 日志目录最大 10M
    fileManager.maximumNumberOfLogFiles = 200; // 日志目录最多 30 个文件
    
    DDFileLogger *fileLogger = [[DDFileLogger alloc] initWithLogFileManager:fileManager];
    fileLogger.maximumFileSize  = 1024 * 1024 * 1; // 单个日志最大 1 M
    fileLogger.rollingFrequency = 60 * 60 * 24; // 单个日志文件有效期
    fileLogger.doNotReuseLogFiles = YES; // 是否重用日志文件
    [fileLogger setLogFormatter:[[UMGlobalLogFileFormatter alloc] init]];
    
    [DDLog addLogger:fileLogger];
    
    UMLog(@"--------------------启动App, 初始化日志--------------------");
    UMLog(@"系统版本: %@, 设备型号: %@, app版本:%@(%@)", [NSString systemVersion], [NSString iPhonePlatform], [NSString appVersion], [NSString buildVersion]);
    UMLog(@"--------------------------------------------------------");
}

+ (void)zipLogsFile:(void (^)(BOOL success, NSString *path))complete {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSString *logsDir = [[self class] logsDir];
        NSString *zipFile = [logsDir stringByAppendingString:@".zip"];
        
        BOOL isDir;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if ([fileManager fileExistsAtPath:zipFile isDirectory:&isDir]) {
            NSError *error;
            [fileManager removeItemAtPath:zipFile error:&error];
            if (error) {
                UMErrorLog(@"上传日志，删除旧文件失败");
            }
        }
        
#ifdef  DEBUG
        BOOL ret = [ZipArchive doZipAtPath:logsDir to:zipFile];
#else
//        BOOL ret = [ZipArchive doZipAtPath:logsDir to:zipFile pwd:@"com.it.one.88"];
        BOOL ret = [ZipArchive doZipAtPath:logsDir to:zipFile];
#endif
        if (ret) {
            BOOL isDir;
            BOOL isExist = [fileManager fileExistsAtPath:zipFile isDirectory:&isDir];
            dispatch_async(dispatch_get_main_queue(), ^{
                if (complete) {
                    complete(isExist, zipFile);
                }
            });
        }
    });
}

+ (void)removeLogs {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSString *logsDir = [[self class] logsDir];
        NSString *zipFile = [logsDir stringByAppendingString:@".zip"];
        
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        BOOL isDir_logs;
        if ([fileManager fileExistsAtPath:logsDir isDirectory:&isDir_logs]) {
            NSError *error;
            [fileManager removeItemAtPath:logsDir error:&error];
            if (error) {
                UMErrorLog(@"Delete logs directory failed. code:%ld ,%@", error.code, error.localizedDescription);
            }
        }
        
        BOOL isDir_zip;
        if ([fileManager fileExistsAtPath:zipFile isDirectory:&isDir_zip]) {
            NSError *error;
            [fileManager removeItemAtPath:zipFile error:&error];
            if (error) {
                UMErrorLog(@"Delete logs zip failed. code:%ld ,%@", error.code, error.localizedDescription);
            }
        }
    });
}

// 查询接口，必要的话上传日志
+ (void)uploadLogsIfNeed {
//    [CyNetObject errorLogCheckHandler:^(CyResult * _Nonnull result) {
//        if (result.isSuccess) {
//            if ([result.data[@"upload"] boolValue]) {
//                NSString *url = result.data[@"url"];
//                if (url.length) {
//                    [[self class] zipLogsFile:^(BOOL success, NSString * _Nonnull path) {
//                        [CyNetObject uploadLogs:path toUrl:url handler:^(CyResult * _Nonnull result) {
//                            if (result.isSuccess) {
//                                
//                            } else {
//                                UMErrorLog(@"upload logs failed.");
//                            }
//                        }];
//                    }];
//                }
//            }
//        }
//    }];
}

// 强制上传日志到服务端 tag
+ (void)uploadLogsToTag:(NSString *)tag {
//    [CyNetObject errorLogCheckHandler:^(CyResult * _Nonnull result) {
//        if (result.isSuccess) {
//            NSString *url = result.data[tag];
//            if (url.length) {
//                [[self class] zipLogsFile:^(BOOL success, NSString * _Nonnull path) {
//                    [CyNetObject uploadLogs:path toUrl:url handler:^(CyResult * _Nonnull result) {
//                        if (result.isSuccess) {
//                            
//                        } else {
//                            UMErrorLog(@"upload logs failed.");
//                        }
//                    }];
//                }];
//            }
//        }
//    }];
}

+ (NSString *)logsDir {
    NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
    NSString *cachePath = [libraryPath stringByAppendingPathComponent:@"Caches"];
    NSString *logsPath = [cachePath stringByAppendingPathComponent:@"Logs"];
    return logsPath;
}

+ (NSString *)net_cfg_err_url_tag {
    return @"net_cfg_err_url";
}

@end

#pragma mark - 目录管理
@implementation UMGlobalLogFileDir

- (NSString *)newLogFileName {
    NSDateFormatter *formatterDir = [[NSDateFormatter alloc] init];
    formatterDir.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
    [formatterDir setDateFormat:@"yyyy-MM-dd HHmmss"];
    NSString *dateDayStr = [formatterDir stringFromDate:[NSDate date]];
    return [NSString stringWithFormat:@"%@ %@.log", LogFileNamePrefix, dateDayStr];
}

- (BOOL)isLogFile:(NSString *)fileName {
    return [fileName hasPrefix:LogFileNamePrefix];
}

@end


#pragma mark - 日志输出格式
@interface UMGlobalLogFileFormatter()

@property (nonatomic, copy) NSString *pidString;

@end

@implementation UMGlobalLogFileFormatter

- (nullable NSString *)formatLogMessage:(DDLogMessage *)logMessage {
    NSString *logLevel;
    switch (logMessage.flag) {
        case DDLogFlagError:    logLevel = @"[E]"; break;
        case DDLogFlagWarning:  logLevel = @"[W]"; break;
        case DDLogFlagInfo:     logLevel = @"[I]"; break;
        case DDLogFlagDebug:    logLevel = @"[D]"; break;
        default:                logLevel = @"[U]"; break; // 未知
    }
    
    if (self.osFormat) {
        return [NSString stringWithFormat:@"%@%@", logLevel, logMessage.message];
    }
    
    return [NSString stringWithFormat:@"%@ PetGuGu[%@:%@] %@%@", [self dateString:logMessage.timestamp], self.pidString, logMessage.threadID, logLevel, logMessage.message];
//    return [NSString stringWithFormat:@"%@ %@ %@(line:%zd) %@: %@\n", [self dateString:logMessage.timestamp], logLevel, logMessage.fileName, logMessage.line, logMessage.function, logMessage.message];
}

- (NSString *)dateString:(NSDate *)date {
    static dispatch_once_t onceToken;
    static NSDateFormatter *dateFormatter;
    dispatch_once(&onceToken, ^{
        dateFormatter = [[NSDateFormatter alloc] init];
        dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
        [dateFormatter setDateFormat:@"YYYY-MM-dd HH:mm:ss.SSSSSSZ"];
    });
    return [dateFormatter stringFromDate:date];
}

- (NSString *)pidString {
    if (!_pidString) {
        _pidString = [NSString stringWithFormat:@"%i", getpid()];
    }
    return _pidString;
}

@end

